package controllers;

import java.util.ArrayList;
import java.util.List;

import models.User;
import play.Logger;
import play.cache.Cache;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Security;
import utils.Key;
import apis.SmartsheetApi;

import com.smartsheet.api.Smartsheet;
import com.smartsheet.api.models.Attachment;
import com.smartsheet.api.models.Row;
import com.smartsheet.api.models.Sheet;

@Security.Authenticated(Secured.class)
public class SmartsheetController extends Controller {
	
	private static final String EMAIL_REGEX = "^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4})$";
	
	/**
	 * Action method to render sheet selection page. 
	 * @return Result
	 */
	public static Result listSheet() {
		// get loginUser
		User loginUser = Application.getLoginUser(request());
		
		List<Sheet> sheets = new ArrayList<Sheet>();
		try {
			Smartsheet smartsheet = SmartsheetApi.getSmartsheet(loginUser);
			// get sheet list
			sheets = SmartsheetApi.getSheets(smartsheet);
			Cache.set(Key.getCacheKey(request(), Key.SHEETS), sheets, Key.CACHE_EXPIRE_30MIN);

	    	Sheet sheet = null; // no selected sheet
	    	if (sheets == null || sheets.isEmpty()) {
	    		Application.setFlash("info", "There is no sheet, create some");
	    	}
//			return ok(menusheet.render(loginUser, sheet, sheets));
		} catch(Exception e) {
			// display error message
			Logger.error("exception on listSheets", e);
			Application.setFlash("warning", "Error to get the sheet list, please try again");
		}
		return redirect(routes.Application.index());
	}
	
	/**
	 * Get the selected sheet from Smartsheet and list the attachments in the sheet, render it in the attachment select page.
	 * @param sheetId the selected sheetId
	 * @return Result
	 */
	public static Result selectSheet(Long sheetId) {
		User loginUser = Application.getLoginUser(request());
		
		// get the sheet list from cache
		List<Sheet> sheets = (List<Sheet>) Cache.get(Key.getCacheKey(request(), Key.SHEETS));
		try {
			Smartsheet smartsheet = SmartsheetApi.getSmartsheet(loginUser);
			if (sheets == null) {
				sheets = SmartsheetApi.getSheets(smartsheet);
			}
			
			Sheet selectedSheet = null;
			for (Sheet sheet : sheets) {
				if (sheet.getId().equals(sheetId)) {
					selectedSheet = sheet;
					break;
				}
			}
			
			if (selectedSheet != null) {
				// get the selected sheet with attachments and rows, save it to session
		    	Sheet sheetObject = SmartsheetApi.getSheet(smartsheet, selectedSheet.getId());

		    	List<Attachment> attachments = null;
		    	List<Row> rows = null;
		    	List<String> attachRowList = new ArrayList<String>();
		    	if (sheetObject != null) {
		    		// save sheet to cache and session
		    		Cache.set(Key.getCacheKey(request(), Key.SHEET), sheetObject, Key.CACHE_EXPIRE_30MIN);
		    		session(Key.SHEET_ID, sheetObject.getId().toString());
		    		
		    		// this always returns null
		    		attachments = sheetObject.getAttachments();
		    		
		    		// sheet does not return any attachment, use attachments from rows
		    		if (attachments == null) {
		    			attachments = new ArrayList<Attachment>();
		    		}
		    		rows = sheetObject.getRows();
		    		for (Row row : rows) {		// rowId starts from 1
		    			String attachStr = "";
		    			List<Attachment> rowAttachments = row.getAttachments();
		    			if (rowAttachments != null && !rowAttachments.isEmpty()) {
		    				int i = 0;
			    	   		for (Attachment attachment : rowAttachments) {
			        			attachStr += row.getId()+","+attachment.getId()+"&"+attachment.getName();
			        			if (i < (rowAttachments.size()-1)) {
			        				attachStr += "/";
			        			}
			        			attachment.setParentId(row.getId());
			        			attachments.add(attachment);
			        			i ++;
			        		}
		    			}
		    			attachRowList.add(attachStr);
		    		}
		    		// success
			    	if (attachments == null || attachments.isEmpty()) {
			    		Application.setFlash("info", "The selected sheet doesn't have an attachment, select other sheet");
			    	}
//			    	return ok(menuattachment.render(loginUser, sheetObject, attachments, rows, attachRowList));
			    	
		    	} else {
		    		// display error message
		    		Logger.info("selectedSheet is null");
		        	Application.setFlash("warning", "Error to get the selected smartsheet, start again");
		    	}
			} else {
				// display error message
				Application.setFlash("warning", "Error to get the selected smartsheet, start again");
			}
		} catch(Exception e) {
			// display error message
			Logger.error("Exception on smartsheet", e);
			Application.setFlash("danger", "Error to get the smartsheet operation, start again");
		}
		//error, redirect to the previous page
//		return redirect(routes.SmartsheetController.listSheet());
		return redirect(routes.Application.index());
	}
	
	/**
	 * Save the selected attachment from browser and render recipient select page.
	 * @param option the selected option, either fromList or fromRow
	 * @param fromList fromList input value, if presents, it indicates the attachment is selected from attachment list
	 * @param fromRow fromRow input value, if presents, it indicates the attachment is selected from row table
	 * @return Result
	 */
	public static Result selectAttachment(String option, String fromList, String fromRow) {
		String attachIds = fromList != null? fromList : fromRow;
		String[] ids = attachIds.split(",");	// it should have rowId,attachmentId
		Long rowId = Long.parseLong(ids[0]);
		Long attachmentId = Long.parseLong(ids[1]);
		
		// get loginUser
		User loginUser = Application.getLoginUser(request());
		
//		try {
//			Smartsheet smartsheet = getSmartsheet(loginUser);
//			// sheets from cache
//			Sheet selectedSheet = (Sheet) Cache.get(Key.getCacheKey(request(), Key.SHEET));
//			if (selectedSheet == null) {
//				selectedSheet = getSheet(smartsheet, Long.parseLong(session(Key.SHEET_ID)));
//			}
//			
//			Attachment selectedAttachment = getAttachment(smartsheet, rowId, attachmentId);
//			// save the attachment to cache
//			Cache.set(Key.getCacheKey(request(), Key.ATTACHMENT), selectedAttachment, Key.CACHE_EXPIRE_30MIN);
//			session(Key.ROW_ID, rowId.toString());
//			session(Key.ATTACHMENT_ID, selectedAttachment.getId().toString());
//
//			// success
////	    	return ok(menurecipient.render(loginUser, MenuConfig.SPECIFY_RECIPIENTS, selectedSheet, selectedAttachment));
//		} catch(Exception e) {
//			// display error message
//			Logger.error("Exception on smartsheet", e);
//			Application.setFlash("danger", "Error to get the attachment, start again");
//		}
		//error, redirect to the previous page
		Long sheetId = Long.parseLong(session(Key.SHEET_ID));
//		return redirect(routes.SmartsheetController.selectSheet(sheetId));
		return redirect(routes.Application.index());
	}
	

    
	/**
	 * Receive the list of recipient name/email from the browser, then move to next confirm dialog page.
	 * @param recipients the list of selected recipient name/email
	 * @return
	 */
//	public static Result selectRecipients(List<String> recipients) {
//		List<Recipient> recipientList = new ArrayList<Recipient>();
//		if (recipients != null) {
//			for (String postData : recipients) {
//				String[] parts = postData.split(",");
//				Recipient recipient = new Recipient();
//				
//				if (parts.length == 1) {	// length == 1, then email only
//					recipient.email = parts[0].trim();
//					//FIXME user name is required to send sign request, put default user name!
//					recipient.name = "Unknown Name";	
//				} else if (parts.length == 2) {		// name,email
//					recipient.name = parts[0].trim();
//					recipient.email = parts[1].trim();
//				}
//				recipientList.add(recipient);
//			}
//		}
//		
//		// get loginUser
//		User loginUser = Application.getLoginUser(request());
//		
//		try {
//			Smartsheet smartsheet = getSmartsheet(loginUser);
//			// get sheets from cache
//			Sheet selectedSheet = (Sheet) Cache.get(Key.getCacheKey(request(), Key.SHEET));
//			if (selectedSheet == null) {
//				selectedSheet = getSheet(smartsheet, Long.parseLong(session(Key.SHEET_ID)));
//			}
//			Attachment selectedAttachment = (Attachment) Cache.get(Key.getCacheKey(request(), Key.ATTACHMENT));
//			if (selectedAttachment == null) {
//				Long rowId = Long.parseLong(session(Key.ROW_ID));
//				Long attachmentId = Long.parseLong(session(Key.ATTACHMENT_ID));
//				selectedAttachment = getAttachment(smartsheet, rowId, attachmentId);
//			}
//			
//			// no recipient selected, send it to sheet owner
//			if (recipientList.isEmpty()) {
//				// find the sheet owner
//				List<Share> shares = (List<Share>) Cache.get(Key.getCacheKey(request(), Key.SHARES));
//				if (shares == null) {
//					shares = getSheetShares(smartsheet, selectedSheet.getId());
//				}
//				if (shares != null && !shares.isEmpty()) {
//					for (Share share : shares) {
//						if (share.getAccessLevel().equals(AccessLevel.OWNER)) {
//							Recipient recipient = new Recipient(share.getName(), share.getEmail());
//							recipientList.add(recipient);
//							break;
//						}
//					}
//				}
//				Application.setFlash("info", "No recipient is selected, the attachment will be sent to sheet owner");
//			}
//	    	return ok(menuconfirm.render(loginUser, MenuConfig.CONFIRM_DIALOG, selectedSheet, selectedAttachment, recipientList));
//	    	
//		} catch(Exception e) {
//			// display error message
//			Logger.error("Exception on smartsheet operation", e);
//			Application.setFlash("danger", "Error to get the sheet owner, start again");
//		}
//		//error, redirect to the previous page
//		String rowId = session(Key.ROW_ID);
//		String attachmentId = session(Key.ATTACHMENT_ID);
//		return redirect(routes.SmartsheetController.selectAttachment("option", rowId+","+attachmentId, null));
//	}
    
	/**
	 * Upload the signed copy of completed document to Smartsheet.
	 * @param signDocument the completed sign document
	 * @param fileName the file name of signed copy
	 * @throws Exception
	 */
//    public static void uploadDocument(SignDocument signDocument, String fileName) throws Exception {
//
//    	Long rowObjectId = signDocument.rowId;
//    	
//    	// call from Connect callback, it means no user.
//		User loginUser = signDocument.user;
//		SmartsheetToken ssToken = loginUser.token;
//		checkTokenExpire(ssToken);
//		
//    	Smartsheet smartsheet = new SmartsheetBuilder().setAccessToken(ssToken.accessToken).build();
//    	RowResources rowResources = smartsheet.rows();
//    	AssociatedAttachmentResources associatedAttachmentResources = rowResources.attachments();
//    	
//    	// upload the signed copy to Smartsheet
//    	File file = new File(fileName);
//    	Logger.info("file getName(): "+file.getName());
//    	String contentType = "application/pdf";
//    	Attachment attachment = associatedAttachmentResources.attachFile(rowObjectId, file, contentType);
//    	
//        Logger.info("Uploaded the signed copy to Smartsheet, attachment id: "+attachment.getId()+", name "+attachment.getName());
//    }


    
}
